import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:game2048/digital_evolution/audio_player_manager.dart';
import 'package:game2048/digital_evolution/game_resultPage.dart';
import 'dart:math';
import 'package:game2048/digital_evolution/login_page.dart';
import 'package:game2048/main.dart';

// 可复用的游戏页面组件
class ReusableGamePage extends StatefulWidget {
  final int checkPointNum;
  const ReusableGamePage({Key? key, required this.checkPointNum})
    : super(key: key);

  @override
  _ReusableGamePageState createState() => _ReusableGamePageState();
}

class _ReusableGamePageState extends State<ReusableGamePage>
    with SingleTickerProviderStateMixin {
  List<List<int>> tracks = List.generate(5, (_) => List.filled(5, 0));
  List<Color> trackColors = List.generate(5, (_) => Color(0xff539F9F));
  List<String> goals = [
    'one2048'.tr(),
    'one2048'.tr(),
    'two2048'.tr(),
    'two2048'.tr(),
    'three2048'.tr(),
  ];
  int nextNumber = 0;
  int maxNumber = 0;
  bool isDropping = false;
  double tubeW = 0.0;
  double blockW = 0.0;
  double trackHeight = 0.0;
  int timeDuration = 250;
  late AnimationController _mergeController;
  late Animation<double> _mergeAnimation;

  @override
  void initState() {
    super.initState();
    generateNextNumber();
    initializeTracks();
    _mergeController = AnimationController(
      vsync: this,
      duration: Duration(milliseconds: timeDuration),
    );
    _mergeAnimation = Tween<double>(begin: 1.0, end: 0.0).animate(
      CurvedAnimation(parent: _mergeController, curve: Curves.easeInOut),
    );
    // 显示游戏说明对话框
    WidgetsBinding.instance.addPostFrameCallback((_) {
      showGameInstructionsDialog();
    });
  }

  void initializeTracks() {
    // 清空所有轨道
    tracks = List.generate(5, (_) => List.filled(5, 0));

    // 根据关卡编号设置初始数字块
    switch (widget.checkPointNum) {
      case 1:
      case 3:
        // 第一关：所有轨道都是0
        break;
      case 2:
      case 4:
      case 5:
        // 第二关：最左边轨道最下面是个2，第二个轨道从下往上是 4 和2，第三个轨道是 8,4,2，第四个轨道是4、2，第五个是 2
        tracks[0][4] = 2; // 第一个轨道最下面
        tracks[1][3] = 2; // 第二个轨道从下往上第二个
        tracks[1][4] = 4; // 第二个轨道最下面
        tracks[2][2] = 2; // 第三个轨道从下往上第三个
        tracks[2][3] = 4; // 第三个轨道从下往上第二个
        tracks[2][4] = 8; // 第三个轨道最下面
        tracks[3][3] = 2; // 第四个轨道从下往上第二个
        tracks[3][4] = 4; // 第四个轨道最下面
        tracks[4][4] = 2; // 第五个轨道最下面
        break;
    }
  }

  void showGameInstructionsDialog() {
    showDialog(
      context: context,
      barrierDismissible: false, // 用户不能通过点击对话框外部关闭
      builder: (BuildContext context) {
        return AlertDialog(
          backgroundColor: Colors.white.withAlpha(220),
          title: Text('gameDescription'.tr()),
          content: Text(
            "gameRule".tr() + "\n" + "levelObjective".tr(namedArgs: {"name":goals[widget.checkPointNum - 1].toString()}),
          ),
          actions: <Widget>[
            TextButton(
              child: Text('startGame'.tr()),
              onPressed: () {
                Navigator.of(context).pop();
              },
            ),
          ],
        );
      },
    );
  }

  void generateNextNumber() {
    Random random = Random();
    double randomValue = random.nextDouble();
    if (randomValue < 0.40) {
      nextNumber = 2;
    } else if (randomValue < 0.70) {
      nextNumber = 4;
    } else if (randomValue < 0.85) {
      nextNumber = 8;
    } else if (randomValue < 0.95) {
      nextNumber = 16;
    } else if (randomValue < 0.99) {
      nextNumber = 32;
    } else {
      nextNumber = 64;
    }
  }

  @override
  Widget build(BuildContext context) {
    double screenW = MediaQuery.of(context).size.width;
    tubeW = (screenW - 30 - 4 * 10) / 5.0;
    blockW = tubeW - 2;
    trackHeight = 5 * tubeW;

    return Scaffold(
      extendBodyBehindAppBar: true,
      appBar: AppBar(
        backgroundColor: Colors.transparent,
        elevation: 0,
        leading: IconButton(
          icon: Icon(Icons.arrow_back),
          onPressed: () {
            Navigator.pop(context);
          },
        ),
        actions: [
          TextButton(
            onPressed: () {
              showGameInstructionsDialog();
            },
            child: Text("description".tr()),
          ),
        ],
        title: Text(
          "levelNumber".tr(
            namedArgs: {"name": widget.checkPointNum.toString()},
          ),
        ),
      ),
      body: Stack(
        children: [
          Positioned(
            bottom: 0,
            left: 0,
            right: 0,
            top: 0,
            child: Image.asset("assets/bg.png", fit: BoxFit.cover),
          ),
          Column(
            children: [
              SizedBox(height: getAppBarHeight(context)),
              Text(
                '${maxNumber.toString()}',
                style: TextStyle(
                  fontSize: 40,
                  fontWeight: FontWeight.bold,
                  color: Colors.red,
                ),
              ),
              SizedBox(height: 10),
              Container(
                child: Center(
                  child: Container(
                    width: blockW,
                    height: blockW,
                    decoration: BoxDecoration(
                      color: getBlockColor(nextNumber),
                      borderRadius: BorderRadius.circular(8),
                      boxShadow: [
                        BoxShadow(
                          color: Colors.black.withOpacity(0.5),
                          offset: Offset(0, 1),
                          blurRadius: 1,
                        ),
                      ],
                    ),
                    child: Center(
                      child: Text(
                        nextNumber.toString(),
                        style: TextStyle(color: Colors.white, fontSize: 24),
                      ),
                    ),
                  ),
                ),
              ),
              SizedBox(height: 50),
              Expanded(
                child: Column(
                  children: [
                    Row(
                      mainAxisAlignment: MainAxisAlignment.spaceEvenly,
                      children: List.generate(5, (index) {
                        return GestureDetector(
                          onTap: () {
                            dropNumber(index);
                          },
                          child: Container(
                            width: tubeW,
                            height: trackHeight,
                            decoration: BoxDecoration(
                              color: trackColors[index],
                            ),
                            child: Column(
                              children: List.generate(5, (index2) {
                                int value = tracks[index][index2];
                                return Expanded(
                                  child: Container(
                                    margin: EdgeInsets.all(1),
                                    decoration: BoxDecoration(
                                      color:
                                          value == 0
                                              ? Colors.transparent
                                              : getBlockColor(value),
                                      borderRadius: BorderRadius.circular(8),
                                    ),
                                    child: Center(
                                      child: Text(
                                        value == 0 ? '' : value.toString(),
                                        style: TextStyle(
                                          color: Colors.white,
                                          fontSize: 24,
                                        ),
                                      ),
                                    ),
                                  ),
                                );
                              }),
                            ),
                          ),
                        );
                      }),
                    ),
                    SizedBox(height: 30),
                    ElevatedButton(
                      onPressed: () {
                        resetGame();
                      },
                      child: Text("restart".tr()),
                    ),
                  ],
                ),
              ),
            ],
          ),
        ],
      ),
    );
  }

  void resetGame() {
    setState(() {
      tracks = List.generate(5, (_) => List.filled(5, 0));
      maxNumber = 0;
      generateNextNumber();
      isDropping = false;
    });
  }

  Color getBlockColor(int value) {
    switch (value) {
      case 2:
        return Colors.lightBlue;
      case 4:
        return Colors.blue;
      case 8:
        return Colors.indigo;
      case 16:
        return Colors.purple;
      case 32:
        return Colors.pink;
      case 64:
        return Colors.red;
      default:
        return Colors.grey;
    }
  }

  double getAppBarHeight(BuildContext context) {
    final appBar = AppBar();
    return appBar.preferredSize.height + MediaQuery.of(context).padding.top;
  }

  void dropNumber(int trackIndex) {
    if (!isDropping) {
      setState(() {
        isDropping = true;
        // 修改处：改变轨道颜色
        trackColors[trackIndex] = Colors.yellow.withAlpha(80);
        if (tracks[trackIndex][0] > 0) {
          EasyLoading.showToast(
            'noMore'.tr(),
            duration: Duration(seconds: 2),
            toastPosition: EasyLoadingToastPosition.center,
          );
          return;
        }
        for (int i = 4; i >= 0; i--) {
          if (tracks[trackIndex][i] == 0) {
            tracks[trackIndex][i] = nextNumber;
            if (tracks[trackIndex][i] > maxNumber) {
              maxNumber = tracks[trackIndex][i];
            }
            break;
          }
        }
        generateNextNumber();
      });

      performVerticalMerge().then((_) {
        performHorizontalMerge().then((_) {
          setState(() {
            isDropping = false;
            // 修改处：恢复轨道颜色
            trackColors[trackIndex] = Color(0xff539F9F);
          });
          checkGameStatus();
        });
      });
    }
  }

  Future<void> performVerticalMerge() async {
    bool canMerge;
    do {
      canMerge = false;
      for (int trackIndex = 0; trackIndex < 5; trackIndex++) {
        for (int j = 4; j > 0; j--) {
          if (tracks[trackIndex][j] == tracks[trackIndex][j - 1] &&
              tracks[trackIndex][j] != 0) {
            await _verticalMerge(trackIndex, j);
            canMerge = true;
          }
        }
        dropDownTracks(trackIndex);
      }
      await Future.delayed(Duration(milliseconds: timeDuration));
    } while (canMerge);
    setState(() {});
  }

  Future<void> performHorizontalMerge() async {
    bool canHorizontalMerge;
    do {
      canHorizontalMerge = false;
      for (int trackIndex = 0; trackIndex < 5; trackIndex++) {
        if (trackIndex > 0) {
          for (int i = 0; i < 5; i++) {
            if (tracks[trackIndex][i] == tracks[trackIndex - 1][i] &&
                tracks[trackIndex][i] != 0) {
              await _horizontalMerge(trackIndex - 1, i);
              canHorizontalMerge = true;
              dropDownTracks(trackIndex - 1);
            }
          }
        }

        if (trackIndex < 4) {
          for (int i = 0; i < 5; i++) {
            if (tracks[trackIndex][i] == tracks[trackIndex + 1][i] &&
                tracks[trackIndex][i] != 0) {
              await _horizontalMerge(trackIndex, i);
              canHorizontalMerge = true;
              dropDownTracks(trackIndex + 1);
            }
          }
        }
      }

      if (canHorizontalMerge) {
        await performVerticalMerge();
      }
      await Future.delayed(Duration(milliseconds: timeDuration));
    } while (canHorizontalMerge);
    setState(() {});
  }

  Future<void> _horizontalMerge(int leftTrackIndex, int numIndex) async {
    AudioManager().playSoundEffect("assets/sounds/clear.wav");
    _mergeController.reset();
    await _mergeController.forward().orCancel;
    setState(() {
      tracks[leftTrackIndex + 1][numIndex] = 0;
      tracks[leftTrackIndex][numIndex] *= 2;
      if (tracks[leftTrackIndex][numIndex] > maxNumber) {
        maxNumber = tracks[leftTrackIndex][numIndex];
      }
    });
  }

  Future<void> _verticalMerge(int trackIndex, int bottomIndex) async {
    _mergeController.reset();
    AudioManager().playSoundEffect("assets/sounds/clear.wav");
    await _mergeController.forward().orCancel;
    setState(() {
      tracks[trackIndex][bottomIndex - 1] = 0;
      tracks[trackIndex][bottomIndex] *= 2;
      if (tracks[trackIndex][bottomIndex] > maxNumber) {
        maxNumber = tracks[trackIndex][bottomIndex];
      }
    });
  }

  void dropDownTracks(int trackIndex) {
    bool canDrop = true;
    while (canDrop) {
      canDrop = false;
      for (int i = 4; i > 0; i--) {
        if (tracks[trackIndex][i] == 0) {
          for (int j = i - 1; j >= 0; j--) {
            if (tracks[trackIndex][j] != 0) {
              tracks[trackIndex][i] = tracks[trackIndex][j];
              tracks[trackIndex][j] = 0;
              canDrop = true;
              break;
            }
          }
        }
      }
    }
    setState(() {});
  }

  void checkGameStatus() {
    bool isGameOver = true;
    for (int i = 0; i < tracks.length; i++) {
      for (int j = 0; j < tracks[i].length; j++) {
        if (tracks[i][j] == 0 || (j > 0 && tracks[i][j] == tracks[i][j - 1])) {
          isGameOver = false;
        }
      }
    }
    if (isGameOver) {
      showResultPage(false);
    }
    int reachNum = 0;
    for (int i = 0; i < tracks.length; i++) {
      for (int j = 0; j < tracks[i].length; j++) {
        if (widget.checkPointNum == 1 || widget.checkPointNum == 2) {
          if (tracks[i][j] == 1024) {
            showResultPage(true);
            break;
          }
        } else if (widget.checkPointNum == 3 || widget.checkPointNum == 4) {
          if (tracks[i][j] == 1024) {
            reachNum += 1;
            if (reachNum >= 2) {
              showResultPage(true);
              break;
            }
          }
        } else if (widget.checkPointNum == 5) {
          if (tracks[i][j] == 1024) {
            reachNum += 1;
            if (reachNum >= 3) {
              showResultPage(true);
              break;
            }
          }
        }
      }
    }
  }

  showResultPage(bool isSuccess) {
    if (isSuccess) {
      GameService.saveLevel(widget.checkPointNum);

      /// 0,第一关
    }
    showDialog(
      context: context,
      barrierColor: Colors.black.withAlpha(100),
      builder:
          (context) => GameResultPage(
            isSuccess: isSuccess,
            checkPointNum: widget.checkPointNum,
            onButtonClick:
                (clickType) => {
                  if (clickType == 1)
                    {
                      Navigator.pop(context),
                      Navigator.pushReplacement(
                        context,
                        MaterialPageRoute(
                          builder:
                              (context) => ReusableGamePage(
                                checkPointNum: widget.checkPointNum + 1,
                              ),
                        ),
                      ),
                      // 下一关
                    }
                  else
                    {
                      Navigator.pop(context),
                      resetGame(),
                      // 重新开始
                    },
                },
          ),
    );
  }

  @override
  void dispose() {
    super.dispose();
    _mergeController.dispose();
  }
}
